package com.lwh.ssl;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

/**
 * @Description:
 * @Date: 2019-09-09
 * @author: luowuhui
 */
@Slf4j
public class QztTrustStrategy implements TrustStrategy {
	private Certificate ca;

	public QztTrustStrategy (URL keyFile) {
		initCertificate(keyFile);
	}

	private void initCertificate (URL keyFile) {
		try (InputStream caInput = keyFile.openStream()) {
			CertificateFactory cf = CertificateFactory.getInstance("X.509");
			this.ca = cf.generateCertificate(caInput);
		} catch (IOException | CertificateException e) {
			log.error("",e);
		}

	}
	/**
	 * Determines whether the certificate chain can be trusted without consulting the trust manager
	 * configured in the actual SSL context. This method can be used to override the standard JSSE
	 * certificate verification process.
	 * <p>
	 * Please note that, if this method returns {@code false}, the trust manager configured
	 * in the actual SSL context can still clear the certificate as trusted.
	 *
	 * @param chain    the peer certificate chain
	 * @param authType the authentication type based on the client certificate
	 * @return {@code true} if the certificate can be trusted without verification by
	 * the trust manager, {@code false} otherwise.
	 * @throws CertificateException thrown if the certificate is not trusted or invalid.
	 */
	@Override
	public boolean isTrusted (X509Certificate[] chain,String authType) throws CertificateException {

		boolean isServerTrusted = true;
		for (X509Certificate cert : chain) {
			cert.checkValidity();
			try {
				//校验签名
				cert.verify(ca.getPublicKey());
			} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException | SignatureException e) {
				e.printStackTrace();
				isServerTrusted = false;
			}
		}
		return isServerTrusted;
	}
}
